# -*- coding: utf-8 -*-
import yaml
from flask import Flask, request, send_file, jsonify
import sqlite3
import uuid
import os
import threading
import logging
import glob
import subprocess # 导入subprocess模块
import io
import zipfile
import json

# --- 全局配置 ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

app = Flask(__name__)
DB_PATH = 'tasks.db'

def create_summary_table():
    import sqlite3
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()

    # 创建任务汇总表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS task_summary (
            task_id TEXT PRIMARY KEY,
            scan_mode TEXT,
            exec_params TEXT,
            task_desc TEXT,
            process_rate REAL,
            status INTEGER DEFAULT 0,
            vul_count TEXT
        )
    ''')

    # 创建扫描器状态表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS scanner_status (
            scanner_name TEXT PRIMARY KEY,
            status TEXT NOT NULL,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    conn.commit()
    conn.close()

# --- 数据库操作函数 ---

def is_scanner_busy(scanner_name):
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute("SELECT status FROM scanner_status WHERE scanner_name = ?", (scanner_name,))
        result = cursor.fetchone()
        return result and result[0] == 'busy'
    except Exception as e:
        logging.error(f"检查扫描器状态时出错: {e}")
        return False
    finally:
        conn.close()

def set_scanner_status(scanner_name, status):
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute('''
            INSERT OR REPLACE INTO scanner_status (scanner_name, status, updated_at) 
            VALUES (?, ?, CURRENT_TIMESTAMP)
        ''', (scanner_name, status))
        conn.commit()
    except Exception as e:
        logging.error(f"设置扫描器状态时出错: {e}")
    finally:
        conn.close()


def insert_task_to_db(task_id, scan_mode, exec_params, task_desc):
    """插入新任务记录"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute('''
            INSERT INTO task_summary (
                task_id, scan_mode, exec_params, task_desc,
                process_rate, status, vul_count
            ) VALUES (?, ?, ?, ?, ?, ?, ?)
        ''', (task_id, scan_mode, exec_params, task_desc, 0.0, 0, '[]'))  # vul_count 默认空 JSON 列表
        conn.commit()
        logging.info(f"任务 {task_id}: 已插入数据库, 执行参数='{exec_params}'")
    except Exception as e:
        conn.rollback()
        logging.error(f"任务 {task_id}: 插入数据库失败: {e}")
        raise
    finally:
        conn.close()

def get_task_by_id_from_db(task_id):
    """根据任务ID获取单个任务记录"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute("SELECT * FROM task_summary WHERE task_id = ?", (task_id,))
        row = cursor.fetchone()
        if row:
            return {
                'task_id': row[0],
                'scan_mode': row[1],
                'exec_params': row[2],
                'task_desc': row[3],
                'process_rate': row[4],
                'status': row[5],
                'vul_count': 'link'
            }
        else:
            return None
    except Exception as e:
        logging.error(f"根据任务ID获取任务信息失败: {e}")
        return None
    finally:
        conn.close()

def get_all_tasks_from_db():
    """获取所有任务记录"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute("SELECT * FROM task_summary")
        rows = cursor.fetchall()
        tasks = []
        for row in rows:
            tasks.append({
                'task_id': row[0],
                'scan_mode': row[1],
                'exec_params': row[2],
                'task_desc': row[3],
                'process_rate': row[4],
                'status': row[5],
                'vul_count': 'link'
            })
        return tasks
    except Exception as e:
        logging.error(f"从数据库获取任务信息失败: {e}")
        return None
    finally:
        conn.close()

def get_vul_count_by_task_id(task_id):
    """根据任务ID获取 vul_count JSON 数据"""
    conn = sqlite3.connect(DB_PATH)
    cursor = conn.cursor()
    try:
        cursor.execute("SELECT task_id, vul_count FROM task_summary WHERE task_id = ?", (task_id,))
        row = cursor.fetchone()
        if row:
            return {
                'task_id': row[0],
                'vul_count': row[1]  # 这里是 JSON 字符串
            }
        else:
            return None
    except Exception as e:
        logging.error(f"获取 vul_count 失败: {e}")
        return None
    finally:
        conn.close()

# --- 后台扫描任务函数 ---
def run_scan_comp(filename, task_id, scanner_path,include_module):
    """在指定扫描器目录中执行 main_process_comp_name.py 脚本。"""
    logging.info(f"任务 {task_id}: 准备在目录 '{scanner_path}' 中执行 main_process_comp_name.py (线程: {threading.current_thread().name})")

    try:
        # 设置扫描器为 busy
        set_scanner_status(scanner_path, 'busy')

        # 构造 subprocess 命令
        if include_module:
            command = ['python3.9', 'main_process_comp_name.py', '-n', filename,'-id',task_id,'-in',include_module]
        else:
            command = ['python3.9', 'main_process_comp_name.py', '-n', filename, '-id', task_id]

        # 执行命令
        process = subprocess.Popen(command, cwd=scanner_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()

        if process.returncode == 0:
            logging.info(f"任务 {task_id}: 在 '{scanner_path}' 中扫描 COMP 配置 完成。")
            logging.info(f"任务 {task_id}: stdout: {stdout.decode()}")
            if stderr:
                logging.warning(f"任务 {task_id}: stderr: {stderr.decode()}")
        else:
            logging.error(f"任务 {task_id}: COMP 扫描失败，退出码: {process.returncode}")
            logging.error(f"任务 {task_id}: stderr: {stderr.decode()}")

    except Exception as e:
        logging.error(f"任务 {task_id}: 在 '{scanner_path}' 中执行 COMP 扫描时出错: {e}")

    finally:
        # 无论成功或失败，都恢复扫描器状态为 idle
        set_scanner_status(scanner_path, 'idle')

def run_scan_batch_api(task_id, scanner_path, include_module):
    """在指定扫描器目录中执行 main_process_batch_api.py 脚本。"""
    logging.info(f"任务 {task_id}: 准备在目录 '{scanner_path}' 中执行 main_process_batch_api.py (线程: {threading.current_thread().name})")

    try:
        # 设置扫描器为 busy
        set_scanner_status(scanner_path, 'busy')

        # 构造 subprocess 命令
        if include_module: # 执行带参数扫描
            command = ['python3.9', 'main_process_batch_api.py', '-id', task_id,'-in',include_module]
        else:
            command = ['python3.9', 'main_process_batch_api.py', '-id', task_id]
        # 执行命令
        process = subprocess.Popen(command, cwd=scanner_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()

        if process.returncode == 0:
            logging.info(f"任务 {task_id}: 在 '{scanner_path}' 中扫描 YAML 配置 完成。")
            logging.info(f"任务 {task_id}: stdout: {stdout.decode()}")
            if stderr:
                logging.warning(f"任务 {task_id}: stderr: {stderr.decode()}")
        else:
            logging.error(f"任务 {task_id}: YAML 扫描失败，退出码: {process.returncode}")
            logging.error(f"任务 {task_id}: stderr: {stderr.decode()}")

    except Exception as e:
        logging.error(f"任务 {task_id}: 在 '{scanner_path}' 中执行 YAML 扫描时出错: {e}")

    finally:
        # 无论成功失败，恢复扫描器状态为 idle
        set_scanner_status(scanner_path, 'idle')

def run_scan_vul_api(task_id, scanner_path, site_id, vul_id, include_module):
    """在指定扫描器目录中执行 main_process_vul_api.py 脚本。"""
    logging.info(f"任务 {task_id}: 准备在目录 '{scanner_path}' 中执行 main_process_vul_api.py (线程: {threading.current_thread().name})")

    try:
        # 设置扫描器为 busy
        set_scanner_status(scanner_path, 'busy')

        # 构造 subprocess 命令
        if include_module: # 执行带参数扫描
            command = ['python3.9', 'main_process_vul_api.py', '-id', task_id,'-s',site_id,'-v',vul_id,'-in',include_module]
        else:
            command = ['python3.9', 'main_process_vul_api.py', '-id', task_id,'-s',site_id,'-v',vul_id]
        # 执行命令
        process = subprocess.Popen(command, cwd=scanner_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()

        if process.returncode == 0:
            logging.info(f"任务 {task_id}: 在 '{scanner_path}' 中扫描 。")
            logging.info(f"任务 {task_id}: stdout: {stdout.decode()}")
            if stderr:
                logging.warning(f"任务 {task_id}: stderr: {stderr.decode()}")
        else:
            logging.error(f"任务 {task_id}: 扫描失败，退出码: {process.returncode}")
            logging.error(f"任务 {task_id}: stderr: {stderr.decode()}")

    except Exception as e:
        logging.error(f"任务 {task_id}: 在 '{scanner_path}' 中扫描时出错: {e}")

    finally:
        # 无论成功失败，恢复扫描器状态为 idle
        set_scanner_status(scanner_path, 'idle')

def run_scan_murl_api(task_id, scanner_path, urls_path, include_module):
    """在指定扫描器目录中执行 main_process_mutil_url.py 脚本。"""
    logging.info(f"任务 {task_id}: 准备在目录 '{scanner_path}' 中执行 main_process_mutil_url.py (线程: {threading.current_thread().name})")

    try:
        # 设置扫描器为 busy
        set_scanner_status(scanner_path, 'busy')

        # 构造 subprocess 命令
        if include_module: # 执行带参数扫描
            command = ['python3.9', 'main_process_mutil_url.py', '-id', task_id,'-f',urls_path,'-in',include_module]
        else:
            command = ['python3.9', 'main_process_mutil_url.py', '-id', task_id,'-f',urls_path]
        # 执行命令
        process = subprocess.Popen(command, cwd=scanner_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()

        if process.returncode == 0:
            logging.info(f"任务 {task_id}: 在 '{scanner_path}' 中扫描 。")
            logging.info(f"任务 {task_id}: stdout: {stdout.decode()}")
            if stderr:
                logging.warning(f"任务 {task_id}: stderr: {stderr.decode()}")
        else:
            logging.error(f"任务 {task_id}: 扫描失败，退出码: {process.returncode}")
            logging.error(f"任务 {task_id}: stderr: {stderr.decode()}")

    except Exception as e:
        logging.error(f"任务 {task_id}: 在 '{scanner_path}' 中扫描时出错: {e}")

    finally:
        # 无论成功失败，恢复扫描器状态为 idle
        set_scanner_status(scanner_path, 'idle')

# --- API 接口定义 ---
@app.route('/api/scanners', methods=['GET'])
def get_available_scanners():
    """提供一个接口，用于获取当前环境下可用的扫描器目录及状态，支持通过 ?name=xx 查询特定扫描器"""
    try:
        query_name = request.args.get('name')  # 获取查询参数

        if query_name:
            # 查询指定扫描器状态
            if not os.path.isdir(query_name):
                return jsonify({'status': 'error', 'message': f'扫描器 {query_name} 不存在'}), 404

            status = 'idle'
            try:
                conn = sqlite3.connect(DB_PATH)
                cursor = conn.cursor()
                cursor.execute("SELECT status FROM scanner_status WHERE scanner_name = ?", (query_name,))
                res = cursor.fetchone()
                if res:
                    status = res[0]
            except Exception as e:
                logging.warning(f"查询扫描器 {query_name} 状态失败: {e}")
            finally:
                conn.close()

            return jsonify({'status': 'success', 'scanner': {'name': query_name, 'status': status}})

        else:
            # 查询所有扫描器状态
            potential_paths = glob.glob('awscan*')
            scanner_directories = [path for path in potential_paths if os.path.isdir(path)]
            logging.info(f"发现可用扫描器目录: {scanner_directories}")

            scanner_list = []
            for scanner in scanner_directories:
                status = 'idle'
                try:
                    conn = sqlite3.connect(DB_PATH)
                    cursor = conn.cursor()
                    cursor.execute("SELECT status FROM scanner_status WHERE scanner_name = ?", (scanner,))
                    res = cursor.fetchone()
                    if res:
                        status = res[0]
                except Exception as e:
                    logging.warning(f"查询扫描器 {scanner} 状态失败: {e}")
                finally:
                    conn.close()

                scanner_list.append({'name': scanner, 'status': status})

            return jsonify({'status': 'success', 'scanners': scanner_list})

    except Exception as e:
        logging.error(f"获取扫描器列表时出错: {e}")
        return jsonify({'status': 'error', 'message': '获取扫描器列表失败'}), 500

@app.route('/api/create_task/comp', methods=['POST'])
def create_comp_task():
    """创建 COMP 扫描任务接口，将 content 写入 .txt 文件中，并执行扫描。"""
    data = request.get_json()
    if not data:
        return jsonify({'status': 'error', 'message': '请求体必须是 JSON 格式'}), 400

    content = data.get('content')
    scanner_name = data.get('scanner_name')
    include_module = data.get('include_module', '')

    if not scanner_name:
        return jsonify({'status': 'error', 'message': '缺少 scanner_name 参数'}), 400

    if is_scanner_busy(scanner_name):
        return jsonify({'status': 'error', 'message': f'扫描器 {scanner_name} 繁忙，请选择其他扫描器'}), 400

    if not content or not isinstance(content, str):
        return jsonify({'status': 'error', 'message': 'content 参数缺失或格式不正确'}), 400

    if not os.path.isdir(scanner_name):
        return jsonify({'status': 'error', 'message': f'扫描器目录无效: {scanner_name}'}), 400

    # 创建任务 ID 和文件路径
    task_id = str(uuid.uuid4())
    comp_filename = f"{content.strip().split()[0]}.txt"
    file_path = os.path.join(scanner_name, comp_filename)

    try:
        # 写入内容到 .txt 文件
        with open(file_path, 'w', encoding='utf-8') as f:
            # 将 content 按空格拆分成列表
            lines = content.strip().split()
            # 将每个元素写入文件的独立一行
            for line in lines:
                f.write(line + '\n')

        # 构造任务信息
        task_desc = comp_filename
        scan_mode = 'comp'
        exec_params = f'file_path={file_path};include_module={include_module}'

        insert_task_to_db(task_id, scan_mode, exec_params, task_desc)

        # 启动后台线程执行扫描
        logging.info(f"任务 {task_id}: 准备启动 COMP 模式扫描器，路径：{scanner_name}")
        threading.Thread(
            target=run_scan_comp,
            args=(comp_filename, task_id, scanner_name,include_module),
            daemon=True
        ).start()

        return jsonify({'status': 'success', 'task_id': task_id, 'message': '任务已提交后台执行'})
    except Exception as e:
        logging.error(f"任务 {task_id}: 创建 COMP 任务失败: {e}")
        return jsonify({'status': 'error', 'message': f'任务创建失败: {e}'}), 500


@app.route('/api/create_task/batch_api', methods=['POST'])
def create_yaml_task():
    """创建 YAML 扫描任务接口，将 config.yaml 写入扫描器目录中。"""
    data = request.get_json()
    if not data:
        return jsonify({'status': 'error', 'message': '请求体必须是 JSON 格式'}), 400

    scan_info = data.get('scanInfo')
    page_size = data.get('pageSize', 10000)
    scanner_name = data.get('scanner_name')
    include_module = data.get('include_module','')

    if is_scanner_busy(scanner_name):
        return jsonify({'status': 'error', 'message': f'扫描器 {scanner_name} 繁忙，请选择其他扫描器'}), 400

    if not scan_info or not isinstance(scan_info, list):
        return jsonify({'status': 'error', 'message': '缺少 scanInfo 或格式不正确'}), 400

    info = next((i for i in scan_info if i.get('scan') is True), None)
    if info:
        filename = f"{info['dbname']}_{info['sitename']}_{info['siteid']}"
        task_desc = filename
    else:
        return jsonify({'status': 'error', 'message': 'scanInfo 没有 scan:true的标记站点'}), 400

    if not scanner_name:
        return jsonify({'status': 'error', 'message': '缺少 scanner_name 参数'}), 400

    if not os.path.isdir(scanner_name):
        return jsonify({'status': 'error', 'message': f"扫描器目录无效: {scanner_name}"}), 400

    # 构造 YAML 内容
    config = {
        'pageSize': page_size,
        'scanInfo': scan_info
    }

    # 写入到 scanner_name/config.yaml 下
    config_path = os.path.join(scanner_name, 'config.yaml')

    try:
        with open(config_path, 'w', encoding='utf-8') as f:
            yaml.dump(config, f, allow_unicode=True)
        logging.info(f"成功写入配置文件: {config_path}")
    except Exception as e:
        logging.error(f"写入配置文件失败: {e}")
        return jsonify({'status': 'error', 'message': f'写入 config.yaml 失败: {e}'}), 500

    task_id = str(uuid.uuid4())
    scan_mode = 'batch_api'
    exec_params = f'config={config_path};scanner={scanner_name};include_module={include_module}'

    try:
        insert_task_to_db(task_id, scan_mode, exec_params, task_desc)

        logging.info(f"任务 {task_id}: 准备启动 YAML 模式扫描器，路径：{scanner_name}")
        scan_thread = threading.Thread(
            target=run_scan_batch_api,  # 你需要实现该扫描逻辑
            args=(task_id, scanner_name, include_module),
            daemon=True
        )
        scan_thread.start()
        return jsonify({'status': 'success', 'task_id': task_id, 'message': '任务已提交后台执行'})
    except Exception as e:
        logging.error(f"任务提交失败: {e}")
        return jsonify({'status': 'error', 'message': f'任务提交失败: {e}'}), 500

@app.route('/api/create_task/vul_api', methods=['POST'])
def create_vul_task():
    """创建 VUL 扫描任务接口"""
    data = request.get_json()
    if not data:
        return jsonify({'status': 'error', 'message': '请求体必须是 JSON 格式'}), 400

    site_id = data.get('siteid')
    vul_id = data.get('vulid')
    scanner_name = data.get('scanner_name')
    include_module = data.get('include_module','')

    if is_scanner_busy(scanner_name):
        return jsonify({'status': 'error', 'message': f'扫描器 {scanner_name} 繁忙，请选择其他扫描器'}), 400
    if site_id and vul_id:
        filename = f"{site_id}_{vul_id}"
        task_desc = filename
    else:
        return jsonify({'status': 'error', 'message': '缺失siteid或vulid参数'}), 400

    if not scanner_name:
        return jsonify({'status': 'error', 'message': '缺少 scanner_name 参数'}), 400

    if not os.path.isdir(scanner_name):
        return jsonify({'status': 'error', 'message': f"扫描器目录无效: {scanner_name}"}), 400


    task_id = str(uuid.uuid4())
    scan_mode = 'vul_api'
    exec_params = f'siteid={site_id};vulid={vul_id};scanner={scanner_name};include_module={include_module}'

    try:
        insert_task_to_db(task_id, scan_mode, exec_params, task_desc)

        logging.info(f"任务 {task_id}: 准备启动 VUL 模式扫描器，路径：{scanner_name}")
        scan_thread = threading.Thread(
            target=run_scan_vul_api,  # 你需要实现该扫描逻辑
            args=(task_id, scanner_name,site_id,vul_id,include_module),
            daemon=True
        )
        scan_thread.start()
        return jsonify({'status': 'success', 'task_id': task_id, 'message': '任务已提交后台执行'})
    except Exception as e:
        logging.error(f"任务提交失败: {e}")
        return jsonify({'status': 'error', 'message': f'任务提交失败: {e}'}), 500

@app.route('/api/create_task/murl_api', methods=['POST'])
def create_murl_task():
    """创建 Murl 扫描任务接口"""
    data = request.get_json()
    if not data:
        return jsonify({'status': 'error', 'message': '请求体必须是 JSON 格式'}), 400

    urls = data.get('urls')
    scanner_name = data.get('scanner_name')
    include_module = data.get('include_module', '')

    if is_scanner_busy(scanner_name):
        return jsonify({'status': 'error', 'message': f'扫描器 {scanner_name} 繁忙，请选择其他扫描器'}), 400

    if not urls:
        return jsonify({'status': 'error', 'message': '缺失urls参数'}), 400

    if not scanner_name:
        return jsonify({'status': 'error', 'message': '缺少 scanner_name 参数'}), 400

    if not os.path.isdir(scanner_name):
        return jsonify({'status': 'error', 'message': f"扫描器目录无效: {scanner_name}"}), 400

    task_id = str(uuid.uuid4())
    scan_mode = 'murl_api'
    task_desc = "多url扫描任务"
    exec_params = f'urls_file={task_id}.txt;scanner={scanner_name};include_module={include_module}'

    try:
        # 将 URL 写入文件
        urls_dir = scanner_name
        os.makedirs(urls_dir, exist_ok=True)
        urls_file_path = os.path.join(urls_dir,f"{task_id}.txt")
        with open(urls_file_path, 'w', encoding='utf-8') as f:
            for url in urls.strip().split():
                f.write(url.strip() + "\n")

        insert_task_to_db(task_id, scan_mode, exec_params, task_desc)

        logging.info(f"任务 {task_id}: 准备启动 Mutil-Url 模式扫描器，路径：{scanner_name}")
        scan_thread = threading.Thread(
            target=run_scan_murl_api,
            args=(task_id, scanner_name, f"{task_id}.txt", include_module),
            daemon=True
        )
        scan_thread.start()
        return jsonify({'status': 'success', 'task_id': task_id, 'message': '任务已提交后台执行'})
    except Exception as e:
        logging.error(f"任务提交失败: {e}")
        return jsonify({'status': 'error', 'message': f'任务提交失败: {e}'}), 500

@app.route('/api/tasks', methods=['GET'])
def get_all_tasks():
    """获取所有任务信息接口"""
    tasks = get_all_tasks_from_db()
    if tasks is not None:
        return jsonify({'status': 'success', 'tasks': tasks})
    else:
        return jsonify({'status': 'error', 'message': '获取任务列表失败'}), 500

@app.route('/api/task/<task_id>', methods=['GET'])
def get_task_by_id(task_id):
    """根据任务ID获取任务信息"""
    task = get_task_by_id_from_db(task_id)
    if task:
        return jsonify({'status': 'success', 'task': task})
    else:
        return jsonify({'status': 'error', 'message': '任务未找到'}), 404
# 新增：下载 API
@app.route('/api/download_vul_json', methods=['GET'])
def download_vul_json():
    task_id = request.args.get('task_id')
    if not task_id:
        return jsonify({'error': 'Missing task_id parameter'}), 400

    task_data = get_vul_count_by_task_id(task_id)
    if not task_data:
        return jsonify({'error': 'Task not found'}), 404

    vul_count_json = task_data.get('vul_count')
    if not vul_count_json:
        return jsonify({'message': '无漏洞数据'}), 200

    try:
        # 尝试加载 JSON 内容
        vul_data = json.loads(vul_count_json)

        # 判断是否为空（例如 [] 或 [[]]）
        is_empty = (
            vul_data == [] or
            vul_data == [[]] or
            (isinstance(vul_data, list) and all(len(item) == 0 for item in vul_data if isinstance(item, list)))
        )

        if is_empty:
            return jsonify({'message': '无漏洞数据'}), 200

        # 转为格式化中文 JSON
        json_bytes = json.dumps(vul_data, indent=2, ensure_ascii=False).encode('utf-8')

        # 打包成 ZIP 文件
        zip_buffer = io.BytesIO()
        with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
            zip_file.writestr(f'{task_id}_vul_data.json', json_bytes)

        zip_buffer.seek(0)
        return send_file(
            zip_buffer,
            mimetype='application/zip',
            as_attachment=True,
            download_name=f'vul_task_{task_id}.zip'
        )

    except json.JSONDecodeError:
        return jsonify({'error': 'vul_count 字段不是合法 JSON'}), 500
    except Exception as e:
        logging.error(f"压缩或返回文件出错: {e}")
        return jsonify({'error': 'Internal server error'}), 500


# --- 应用启动入口 ---
if __name__ == '__main__':
    # 检查数据库文件是否存在
    if not os.path.exists(DB_PATH):
        print("数据库不存在，正在初始化...")
        create_summary_table()
    app.run(host='0.0.0.0', port=46130, debug=False)